package cn.tedu.lbs.basic.web.service;

import cn.tedu.lbs.basic.web.repository.AdminRepository;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.common.passport.encoder.JwtEncoder;
import com.tarena.lbs.common.passport.enums.Roles;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.pojo.basic.po.AdminPO;
import com.tarena.lbs.pojo.passport.param.AdminLoginParam;
import com.tarena.lbs.pojo.passport.vo.LoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 当前service代表的是业务功能 登录
 */
@Service
public class LoginService {
    //后台登录 操作的表格lbs_admin
    @Autowired
    private AdminRepository adminRepository;
    @Autowired
    private JwtEncoder jwtEncoder;

    public LoginVO doLogin(AdminLoginParam param) throws BusinessException {
        //1.根据param中的phone查询是否存在adminPO
        AdminPO po=checkAndGetAdmin(param.getPhone());
        //2.验证密码 po的密码 和param密码是否相等
        matchPasswords(po.getAccountPassword(),param.getPassword());
        //TODO 3.对于jwt一无所知 暂时给一个假的
        String jwt=generateJwt(po.getId(),po.getNickname(),
                po.getAccountType()==0?Roles.ADMIN:Roles.SHOP);
        //4.返回一个LoginVO给控制层使用
        LoginVO vo=new LoginVO(jwt,po.getId(),po.getNickname());
        return vo;
    }

    private void matchPasswords(String accountPassword, String password) throws BusinessException {
        //1.阅读工具源码 两个字符串 都是null 返回true
        //2.有一个不是空返回equals相等结果
        boolean equals = StringUtils.equals(accountPassword, password);
        Asserts.isTrue(!equals,new BusinessException("-2","提交的密码不正确"));
    }

    private String generateJwt(Integer id, String nickname, Roles role) throws BusinessException {
        //1.JwtEncoder如何获取  盐如何定义
        //2.jwt保存什么数据 AdminPO吗?
        //2.1问题 属性太多 远比需要的多很多 比如password status
        //2.2问题 不能复用 比如小程序登录 就不能再使用这个方法
        //2.3问题 封装到jwt的对象也要 全局统一 认证对象
        UserPrinciple principle=new UserPrinciple();
        principle.setId(id);
        principle.setNickname(nickname);
        principle.setRole(role);
        return jwtEncoder.generateToken(principle);
    }
    private AdminPO checkAndGetAdmin(String phone) throws BusinessException {
        //select * from lbs_admin where account_phone=?
        QueryWrapper<AdminPO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("account_phone",phone);
        //仓储层现在 也是可以交给mybatis-plus直接帮助我们实现sql的一个bean对象了
        AdminPO po = adminRepository.getOne(queryWrapper);
        //如果拿不到 考虑抛异常
        //优化点1 但凡发现 满足某个表达式 就抛异常-->断言思想Assert
        /*if(po==null){
            throw new RuntimeException("账号不存在");
        }*/
        //优化点2 断言逻辑 一般都属于业务断言 抛业务异常
        //当前项目 封装了所有断言抛出的业务异常 BusinessException(code,message)
        Asserts.isTrue(po==null,new BusinessException("-2","电话号码不存在"));
        return po;
    }
}
